package com.jiangyifen.robot.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.jiangyifen.framework.db.dao.SuperDao;
import com.jiangyifen.framework.db.util.DbUtil;
import com.jiangyifen.robot.core.Robot;
import com.jiangyifen.robot.core.session.RobotSession;
import com.jiangyifen.robot.entity.ChatNodeEntity;
import com.jiangyifen.robot.entity.ChatRecordEntity;
import com.jiangyifen.robot.entity.ScenarioEntity;
import com.jiangyifen.robot.service.RobotSessionService;

@Service
public class RobotSessionServiceImpl implements RobotSessionService {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private SuperDao superDao;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	private Queue<ChatRecordEntity> chatRecordEntitySaveQueue = new LinkedBlockingQueue<>();

	@PostConstruct
	private void init() {
		new Thread(() -> {
			while (true) {
				try {
					Thread.sleep(1000);
					// 从内存中批量取出待保存的ChatRecordEntity
					// 取完，或者取满5000条，就保存一次
					List<ChatRecordEntity> list = new ArrayList<>();
					ChatRecordEntity chatRecordEntity = null;
					int count = 0;
					while ((chatRecordEntity = chatRecordEntitySaveQueue.poll()) != null && count < 5000) {
						list.add(chatRecordEntity);
						count++;
					}

					// 存！！
					superDao.save(list);

				} catch (Exception e) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
						logger.error(e.getMessage(), e);
					}
					logger.error(e.getMessage(), e);
				}
			}
		}).start();
	}

	@Override
	public RobotSession getNewSession(Long scenarioId, Robot robot) {
		RobotSession session = new RobotSession();
		session.setRobot(robot);

		ScenarioEntity scenarioEntity = superDao.get(scenarioId, ScenarioEntity.class);
		session.setScenarioEntity(scenarioEntity);

		Map<Long, ChatNodeEntity> chatNodes = getChatNodesByScenarioId(scenarioId);
		session.setChatNodeEntityMap(chatNodes);

		ChatNodeEntity firstChatNodeEntity = getFirstChatNode(scenarioId);
		session.setFirstChatNodeEntity(firstChatNodeEntity);
		if (firstChatNodeEntity != null && firstChatNodeEntity.getIsMainNode()) {
			session.setCurrentChatNodeEntity(firstChatNodeEntity);
		}

		return session;
	}

	@Override
	public Map<Long, ChatNodeEntity> getChatNodesByScenarioId(Long scenarioId) {
		Map<Long, ChatNodeEntity> result = new HashMap<>();
		try {

			String sql = "SELECT * FROM `" + DbUtil.getDbname() + "`.`" + DbUtil.getTableName(ChatNodeEntity.class)
					+ "` WHERE scenarioId=?";
			List<ChatNodeEntity> list = jdbcTemplate.query(sql,
					new BeanPropertyRowMapper<ChatNodeEntity>(ChatNodeEntity.class), scenarioId);

			for (ChatNodeEntity chatNodeEntity : list) {
				result.put(chatNodeEntity.getId(), chatNodeEntity);
			}

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	@Override
	public ChatNodeEntity getFirstChatNode(Long scenarioId) {
		ChatNodeEntity result = null;
		try {
			String sql = "SELECT * FROM `" + DbUtil.getDbname() + "`.`" + DbUtil.getTableName(ChatNodeEntity.class)
					+ "` WHERE scenarioId=? and isFirstNode=1 ORDER BY id LIMIT 1";
			result = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<ChatNodeEntity>(ChatNodeEntity.class),
					scenarioId);
		} catch (Exception e) {
			// logger.error(e.getMessage(), e);
			logger.error(e.getMessage());
			logger.error("获取首节点失败：scenarioId={}", scenarioId);
		}
		return result;
	}

	@Override
	public ChatNodeEntity getChatNodeEntity(Long chatNodeEntityId) {
		return superDao.get(chatNodeEntityId, ChatNodeEntity.class);
	}

	@Override
	public ChatNodeEntity getChatNodeEntity(String nodeCode) {
		ChatNodeEntity result = null;
		try {
			String sql = "SELECT * FROM `" + DbUtil.getDbname() + "`.`" + DbUtil.getTableName(ChatNodeEntity.class)
					+ "` WHERE nodeCode=? LIMIT 1";
			result = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<ChatNodeEntity>(ChatNodeEntity.class),
					nodeCode);
		} catch (Exception e) {
			logger.error("nodeCode={}, 数据库里没有对应的对话节点", nodeCode);
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	@Override
	public void saveChatRecord(ChatRecordEntity chatRecordEntity) {
		chatRecordEntitySaveQueue.offer(chatRecordEntity);
	}

}
